"""
cdn.sync

Contains functions responsible for maintaining content storage and database table.
These function can be triggered through the web interface.

The script cdn_daemon.py runs in a separate thread and periodically triggers these 
through the web interface. 
"""
### Start of imports

# This line just better work...
from jackson import debug

# There's debug stuff for the rest
debug.pre_import(__name__)

debug.importing(__name__, 'choice from random', 3)
from random import choice

debug.importing(__name__, 'File from django.core.files', 2)
from django.core.files import File

debug.importing(__name__, 'ContentEntry from jackson.cdn.models')
from jackson.cdn.models import ContentEntry

debug.importing(__name__, 'core, net from jackson.cdn')
from jackson.cdn import core, net

import jackson.extjson.ext_json as json

debug.post_import(__name__)

### End of imports

def clean_content():
    """ Deletes files and content entries we don't need any more.
    @author: ep
    @rtype: None
    """
    context = [__name__, 'clean_content()']
    debug.enter(context, None, 3)
    try:
        # Collect outgoing ContentEntrys
        debug.comment(context, 'Collecting outgoing ContentEntry rows', 3)
        qs = ContentEntry.objects.filter(status='O')
        
        # If we didn't find any, just return
        count = qs.count()
        if count == 0:
            debug.comment(context, "There aren't any", 3)
            debug.leave(context, None, 3)
            return
        
        # Pick an entry at random
        #@note: count != 0 implies this won't throw an exception
        debug.comment(context, 'Picking a random outgoing ContentEntry', 3)
        entry = qs[choice(range(0,count))].get()
        
        # Check f this file was successfully downloaded by entry.server
        debug.comment(context, 'Checking if this file has been transferred off the server', 3)
        res = net.confirm_distribution(entry.server, entry.key) 
        if res.has_key('success?'):
            debug.comment(context, 'It has been transferred - deleting local copy', 3)
            # Delete file
            core.delete_content(entry)
            # Delete entry
            entry.delete()
        else:
            debug.comment(context, "It hasn't been transferred yet - retaining local copy", 3)
        result = { 'success?' : True }
    except Exception, e:
        debug.exception(context, str(e))
        result = { 'exception' : str(e) }
        
    debug.leave(context, result, 3)
    return result


def poke_content():
    """ Pokes servers expecting files from us.
    @author: ep
    @return: True if there was something to poke, False otherwise 
    """
    context = [__name__, 'poke_content()']
    debug.enter(context, None, 3)
    try:
        # Pick a random outgoing entry if there is any,
        debug.comment(context, 'Collecting outgoing ContentEntry rows', 3)
        qs = ContentEntry.objects.filter(status='O')
        count = qs.count()
        
        if count == 0:
            debug.comment(context, "There aren't any", 3)
            debug.leave(context, { 'success?' : False }, 3)
            return { 'success?' : False }
        
        debug.comment(context, 'Picking a random ContentEntry', 3)
        # @change: 3-14-09
        entry = choice(qs)
        
        # and poke it
        debug.comment(context, 'Poking custodian server', 3)
        # @change: this now creates the server instead of passing in the string
        net.poke(entry.server, entry.key)
        
        result = { 'success?' : True }
    except Exception, e:
        debug.exception(context, str(e))
        result = { 'exception' : str(e) }
    
    debug.leave(context, result, 3)
    return result


def collect_content():
    """ Attempts to download a random piece of content this server is responsible for but doesn't have.
    @author: ep
    @rtype: None
    """
    context = [__name__, 'collect_content()']
    debug.enter(context, {'asdf':'asdf'})
    # Try to get the most urgent incoming entry
    debug.comment(context, 'Looking for highest priority content', 3)
    entry = ContentEntry.objects.filter(status='I').order_by('-urgency')[0:1].get()
    # If it worked (ie no exception was thrown)
    # try downloading the associated content
    debug.comment(context, 'downloading' + str(entry))
    core.get_content(entry)
    result = True
    
    debug.leave(context,  {'asdf':'asdf'})
    return result
